/************************************************************************
 * @file ConfigDialog.cpp
 * @author Ian Chen
 * @version 1.0
 *
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 *
 ************************************************************************/
#include <QFrame>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>

#include <pluginui/widget/ConfigDialog.h>
#include <pluginui/widget/ConfigPanel.h>
#include <pluginui/manager/ConfigPanelManager.h>
#include <qwwconfigwidget/QwwConfigWidget>
#include <plugin/util/Framework.h>

namespace antu
{
namespace plugin
{
namespace ui
{
ConfigDialog::ConfigDialog(ConfigPanelManager* pManager, QWidget *parent)
    : QDialog(parent),
      m_pManager(pManager)
{
    this->setWindowModality(Qt::ApplicationModal);
    this->setWindowTitle(tr("System Configuration"));
    this->setWindowIcon(QIcon(":/images/Resources/gear_16.png"));

    // construct gui
    QVBoxLayout* pMainLayout = new QVBoxLayout;
    QHBoxLayout* pButtonLayout = new QHBoxLayout;
    QHBoxLayout* pContentLayout = new QHBoxLayout;
    this->m_pConfigWidget = new QwwConfigWidget();//this);
    pContentLayout->addWidget(this->m_pConfigWidget);

    // create buttons
    QPushButton* pConfirm = new QPushButton(this);
    pConfirm->setText(tr("Confirm"));
    connect(pConfirm, SIGNAL(clicked()), this, SLOT(confirm()));

    QPushButton* pCancel = new QPushButton(this);
    pCancel->setText(tr("Cancel"));
    connect(pCancel, SIGNAL(clicked()), this, SLOT(cancel()));

    QPushButton* pApply = new QPushButton(this);
    pApply->setText(tr("Apply"));
    connect(pApply, SIGNAL(clicked()), this, SLOT(apply()));

    // fill buttons
    pButtonLayout->addStretch(1);
    pButtonLayout->addWidget(pConfirm);
    pButtonLayout->addWidget(pCancel);
    pButtonLayout->addWidget(pApply);

    QFrame* pFrame = new QFrame(this);
    pFrame->setFrameShape(QFrame::HLine);
    pFrame->setFrameShadow(QFrame::Sunken);
    pMainLayout->addLayout(pContentLayout);
    pMainLayout->addWidget(pFrame);
    pMainLayout->addLayout(pButtonLayout);

    this->setLayout(pMainLayout);

    if (this->m_pManager != nullptr)
    {
        for (size_t i = 0; i < this->m_pManager->size(); i++)
        {
            ConfigPanelItemStruct item = this->m_pManager->at(i);
            item.pPanel->load();
            this->m_pConfigWidget->addGroup(item.pPanel, item.icon, item.title);
        }
    }

    QSize size = this->size();

    int w = size.width();
    int h = size.height();

    if (w * 0.618 < h)
    {
        size.setWidth((int)(h / 0.618));
    }
    else
    {
        size.setHeight((int)(w * 0.618));
    }
    this->resize(size);
}

ConfigDialog::~ConfigDialog()
{
    if (this->m_pManager != nullptr)
    {
		for (size_t i = 0; i < this->m_pManager->size(); i++)
		{
			ConfigPanelItemStruct item = this->m_pManager->at(i);
			item.pPanel->setParent(nullptr);
		}
    }
}

void ConfigDialog::confirm()
{
    this->apply();
    this->close();
}

void ConfigDialog::cancel()
{
    // do nothing
    this->close();
}

void ConfigDialog::apply()
{
    for (int i = 0; i < this->m_pConfigWidget->count(); i++)
    {
        ConfigPanel* pWidget = qobject_cast<ConfigPanel*>(this->m_pConfigWidget->group(i));

        if (nullptr != pWidget && pWidget->contentHashChanged())
        {
            pWidget->save();
            emit pWidget->saved();
            pWidget->reset();
        }
    }
    Framework::Instance.settingsManager()->sync();
}

bool ConfigDialog::isEmpty()
{
    return this->m_pManager == nullptr ||
            this->m_pManager->isEmpty();
}

const char* ConfigDialog::CONFIG_DLG = "CONFIG_DIALOG";

}
}
}
